import math
import os
import re
import shutil
import traceback

import fitz
from PIL import Image
from pandas import Interval


def formating_recognized_texts(recognized_line_list_in_one_page, threshold=0):
    recognized_line_list_in_one_page.sort(key=lambda i: (i[0][0][0]))  # 按照x排
    already_IN, line_list = [], []
    for i in range(len(recognized_line_list_in_one_page)):  # i当前
        if recognized_line_list_in_one_page[i][0][0] in already_IN:
            continue
        line_txt = recognized_line_list_in_one_page[i][1][0]
        already_IN.append(recognized_line_list_in_one_page[i][0][0])
        # print(res[i])
        y_i_points = [recognized_line_list_in_one_page[i][0][0][1], recognized_line_list_in_one_page[i][0][1][1],
                      recognized_line_list_in_one_page[i][0][3][1], recognized_line_list_in_one_page[i][0][2][1]]
        min_I_y, max_I_y = min(y_i_points), max(y_i_points)
        curr = Interval(min_I_y + (max_I_y - min_I_y) // 3, max_I_y)
        curr_mid = min_I_y + (max_I_y - min_I_y) // 2

        for j in range(i + 1, len(recognized_line_list_in_one_page)):  # j下一个
            if recognized_line_list_in_one_page[j][0][0] in already_IN:
                continue
            y_j_points = [recognized_line_list_in_one_page[j][0][0][1], recognized_line_list_in_one_page[j][0][1][1],
                          recognized_line_list_in_one_page[j][0][3][1], recognized_line_list_in_one_page[j][0][2][1]]
            min_J_y, max_J_y = min(y_j_points), max(y_j_points)
            next_j = Interval(min_J_y, max_J_y - (max_J_y - min_J_y) // 3)

            if next_j.overlaps(curr) and curr_mid in Interval(min_J_y, max_J_y):
                line_txt += (recognized_line_list_in_one_page[j][1][0] + "  ")
                already_IN.append(recognized_line_list_in_one_page[j][0][0])
                curr = Interval(min_J_y + (max_J_y - min_J_y) // 3, max_J_y)
                curr_mid = min_J_y + (max_J_y - min_J_y) // 2
        line_list.append((recognized_line_list_in_one_page[i][0][0][1], line_txt))
    line_list.sort(key=lambda x: x[0])

    whole_strings_in_one_page = '\n'.join([i[1] for i in line_list])
    info_list_in_one_page = [i[1] for i in line_list]
    return whole_strings_in_one_page, info_list_in_one_page


def extract_infos_from_lines(strings, prefix):
    # 初始化结果列表
    results = []
    # 遍历字符串列表
    for item in strings:
        # 检查字符串是否以指定前缀开头
        if item.strip().startswith(prefix):
            # 去除字符串前后的空格，然后提取前缀之后的内容
            info = item[len(prefix):].strip()
            # 将提取的信息添加到结果列表中
            results.append(info)
    return results


"""
 抽取通用代码
 总层数[^\\\\]*?息(.*)
"""


def extract_info(match_pattern, whole_strings_in_one_page, filter_list=[]):
    result_str = ''
    if re.search(match_pattern, whole_strings_in_one_page):
        result = re.findall(match_pattern, whole_strings_in_one_page)
        if len(result) > 0:
            result_str = result[0]
    result_str = result_str.replace("\n", "")
    result_str = re.sub(r"\s+", "", result_str)

    for filter_str in filter_list:
        result_str = result_str.replace(filter_str, "")
    # for special in ['_','——','-','-']:
    #     result_str = result_str.replace(special, "")
    return result_str



# def split_pdf(target_pdf_path):
#     with fitz.open(target_pdf_path) as pdf:
#         page_image_list = []
#         for page_index in range(0, pdf.page_count):
#             page = pdf[page_index]
#             mat = fitz.Matrix(4.0, 4.0)
#             pm = page.get_pixmap(matrix=mat, alpha=False)
#
#             img = Image.frombytes("RGB", [pm.width, pm.height], pm.samples)
#             img = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
#             page_image_list.append(img)
#     return page_image_list

def split_pdf_to_single_page_pdf(pdf_path, output_folder_path):
    # 打开PDF文件
    pdf = fitz.open(pdf_path)
    num_pages = pdf.pageCount

    # 创建输出文件夹
    if not os.path.exists(output_folder_path):
        os.makedirs(output_folder_path)

    # 遍历每一页，将每一页保存为单独的PDF文件
    for i in range(num_pages):
        page = pdf.load_page(i)  # 加载每一页
        output_filename = os.path.join(output_folder_path, f"page_{i + 1}.pdf")
        page.save(output_filename)  # 保存每一页为单独的PDF文件

    pdf.close()
    print(f"PDF文件已拆分到 {output_folder_path}")


def split_pdf(target_pdf_path):
    with fitz.open(target_pdf_path) as pdf:
        page_image_list = []
        for page_index in range(pdf.page_count):
            page = pdf[page_index]
            mat = fitz.Matrix(4.0, 4.0)
            pm = page.get_pixmap(matrix=mat)
            # 将Pixmap转换为PIL Image对象
            img = Image.frombytes(
                "RGB",
                (pm.width, pm.height),
                pm.samples
            )
            # 如果需要使用cv2进行处理，请确保最后转换回PIL Image对象
            # img_cv2 = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
            # img = Image.fromarray(cv2.cvtColor(img_cv2, cv2.COLOR_BGR2RGB))
            page_image_list.append(img)
    return page_image_list


def is_single_page_pdf(file_path):
    doc = fitz.open(file_path)  # 打开PDF文件
    page_count = doc.page_count  # 获取PDF文件的页数
    doc.close()  # 关闭PDF文件
    return page_count == 1  # 如果页数为1，则返回True


def convert_pdf_to_jpg_and_collect_paths(input_directory, output_directory):
    # 初始化存储JPG文件路径的列表
    jpg_paths = []

    # 确保输出目录存在
    if not os.path.exists(output_directory):
        os.makedirs(output_directory)

    # 遍历输入目录下的所有文件
    for filename in os.listdir(input_directory):
        if filename.lower().endswith('.pdf'):
            # 构建PDF文件的完整路径
            pdf_path = os.path.join(input_directory, filename)
            # 使用pdf2image转换PDF为图像列表
            images = split_pdf(pdf_path)
            # 遍历图像列表，保存每一页为JPG格式
            for i, image in enumerate(images, start=1):
                # 构建JPG文件名，格式为：原始文件名_页码.jpg
                jpg_filename = f"{os.path.splitext(filename)[0]}_{i}.jpg"
                jpg_path = os.path.join(output_directory, jpg_filename)
                # 保存图像为JPEG格式
                image.save(jpg_path, 'JPEG')
                # 将JPG文件的路径添加到列表中
                jpg_paths.append(jpg_path)
                print(f'Converted page {i} of {pdf_path} to {jpg_path}')

    # 返回包含所有JPG文件路径的列表
    return jpg_paths


def create_directory_if_not_exists(path):
    if not os.path.exists(path):
        os.makedirs(path)
        print(f"路径 {path} 已经被创建！")
    else:
        print(f"路径 {path} 已经存在.")


def crop_and_save_image(image_path, crop_area, output_path):
    """
    截取图片中的固定位置并保存。

    参数:
    image_path (str): 输入图片的路径。
    crop_area (tuple): 一个包含四个元素的元组，表示截取区域的左上角和右下角的坐标 (left, upper, right, lower)。
    output_path (str): 输出图片的路径。
    """
    # 打开图片
    img = Image.open(image_path)

    # 截取图片
    left, upper, right, lower = crop_area
    cropped_img = img.crop((left, upper, right, lower))

    # 保存截取后的图片
    cropped_img.save(output_path)
    img.close()


def get_error_file_name_and_line_number(e):
    file_name_and_line_number = ""
    for tb in traceback.extract_tb(e.__traceback__):
        file_name_and_line_number = file_name_and_line_number + "文件:" + str(tb.filename) + "\n"
        print("文件:", tb.filename)
        file_name_and_line_number = file_name_and_line_number + "行号:" + str(tb.lineno) + "\n"
        print("行号:", tb.lineno)

    return file_name_and_line_number


def move_file(original_file_path, destination_dir_path):
    # 检查目标位置是否存在
        destination_path = os.path.join(destination_dir_path, os.path.basename(original_file_path))
        if os.path.exists(destination_path):
            # 如果是文件，使用os.remove()删除
            if os.path.isfile(destination_path):
                os.remove(destination_path)
        shutil.move(original_file_path, destination_path)

def rotate_image_and_adjust_size(img, angle):
    # 定义大小
    new_size = (img.width, img.height)

    # 旋转图像
    rotated_img = img.transform(new_size, Image.AFFINE, (
        math.cos(math.radians(angle)), math.sin(math.radians(angle)), 0, -math.sin(math.radians(angle)),
        math.cos(math.radians(angle)), 0))

    return rotated_img


def keep_from_guang(text):
    # 定义要查找的字符
    target = "广"

    # 查找字符在文本中的位置
    start_index = text.find(target)

    # 检查字符串是否以“州”字开头,# 如果不是，补齐“广”字
    if start_index == -1:
        return r'广' + text
    elif text.startswith(target):
        return text
    # 如果找到了字符，并且不是以“广”字开头
    else:
        # 截取从“广”字开始后的内容，包括“广”字
        return text[start_index:]
